<template>
    <div class="icon-select">
        <a-popover placement="bottom" trigger="click" v-model:open="visible"
            :style="{ width: `${state.popoverWidth}px` }">
            <template #content>
                <a-tabs v-model:activeKey="activeKey">
                    <a-tab-pane v-for="tab in iconTabsMap" :key="tab.name" :tab="tab.name">
                        <div class="h-[280px] overflow-y-auto w-[400px]">
                            <div class="flex flex-wrap">
                                <div v-for="item in iconNamesFliter" :key="item" class="m-1">
                                    <a-button @click="handleSelect(item)">
                                        <icon :name="item" />
                                    </a-button>
                                </div>
                            </div>
                        </div>
                        <div class="mt-2 text-center">
                            <a-pagination v-model:current="currentPage" :total="filteredIcons.length"
                                :pageSize="pageSize" size="small" @change="handlePageChange" />
                        </div>
                    </a-tab-pane>
                </a-tabs>
            </template>
            <a-input ref="inputRef" :value="modelValue" @input="(e: Event) => {
                const value = (e.target as HTMLInputElement).value;
                debouncedSearch(value);
                emits('update:modelValue', value);
            }" placeholder="搜索图标" :autofocus="false" allowClear>
                <template #prefix>
                    <Icon :name="modelValue == '' ? 'ant-icon-UserOutlined' : modelValue" />
                </template>
            </a-input>
        </a-popover>
    </div>
</template>

<script lang="ts" setup>
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
import { useEventListener } from '@vueuse/core'
import { getAntdIconList, getLocalIconNames } from './index'
import { useDebounceFn } from '@vueuse/core'
interface Props {
    modelValue: string
}

const props = withDefaults(defineProps<Props>(), {
    modelValue: '',
});

const emits = defineEmits<{
    (e: 'update:modelValue', value: string): void
    (e: 'change', value: string): void
}>();

const tabIndex = ref(0)
const activeKey = ref('Ant Design 图标')
const iconTabsMap = [
    {
        name: 'Ant Design 图标',
        icons: getAntdIconList()
    },
    {
        name: '本地图标',
        icons: getLocalIconNames()
    }
]

const inputRef = ref()
const visible = ref(false)
const state = reactive({
    inputValue: '',
    popoverWidth: 0,
    mouseoverSelect: false,
    inputFocus: false,
    popoverVisible: false
})

const pageSize = 42
const currentPage = ref(1)


// 选中图标
const handleSelect = (icon: string) => {
    updateValue(icon);
    visible.value = false;
}

//取消选中
const handleClear = () => {
    emits('update:modelValue', '')
    emits('change', '')
}


const updateValue = (value: string) => {
    emits('update:modelValue', value);
    emits('change', value);
};


// 获取当前页的图标
const getCurrentPageIcons = (icons: string[]) => {
    const start = (currentPage.value - 1) * pageSize
    const end = start + pageSize
    return icons.slice(start, end)
}

// 页码改变
const handlePageChange = (page: number) => {
    currentPage.value = page
}

// 重置分页
const resetPagination = () => {
    currentPage.value = 1
}

// 监听搜索和标签切换，重置分页
watch([() => state.inputValue, activeKey], () => {
    resetPagination()
})

//根据输入框内容筛选
const filteredIcons = computed(() => {
    const iconNames = iconTabsMap[tabIndex.value]?.icons ?? []
    if (!state.inputValue) {
        return iconNames
    }
    const inputValue = state.inputValue.toLowerCase()
    return iconNames.filter((icon: string) => {
        if (icon.toLowerCase().indexOf(inputValue) !== -1) {
            return icon
        }
    })
})

// 当前显示的图标
const iconNamesFliter = computed(() => {
    return getCurrentPageIcons(filteredIcons.value)
})

// 防抖处理搜索
const debouncedSearch = useDebounceFn((value: string) => {
    state.inputValue = value
}, 300)

// 监听标签页切换
watch(activeKey, (newVal) => {
    tabIndex.value = iconTabsMap.findIndex(tab => tab.name === newVal)
})

// 获取 input 的宽度
const getInputWidth = () => {
    nextTick(() => {
        const inputWidth = inputRef.value?.$el.offsetWidth
        state.popoverWidth = inputWidth
    })
}

//监听body点击事件
useEventListener(document.body, 'click', () => {
    state.popoverVisible = state.inputFocus || state.mouseoverSelect ? true : false
})

watch(
    () => state.popoverVisible,
    async (value) => {
        await nextTick()
        if (value) {
            inputRef.value?.focus()
        } else {
            inputRef.value?.blur()
        }
    }
)

onMounted(() => {
    getInputWidth()
})
</script>
